package com.ruoyi.entry.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.commodity.domain.MCommodity;
import com.ruoyi.stock.domain.MStock;
import com.ruoyi.stock.mapper.MStockMapper;
import com.ruoyi.warehouse.domain.MWarehouse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.entry.mapper.MEntryMapper;
import com.ruoyi.entry.domain.MEntry;
import com.ruoyi.entry.service.IMEntryService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入库管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-10-24
 */
@Service
public class MEntryServiceImpl implements IMEntryService 
{
    @Autowired
    private MEntryMapper mEntryMapper;

    @Autowired
    private MStockMapper mStockMapper;



    /**
     * 查询入库管理
     * 
     * @param entryId 入库管理主键
     * @return 入库管理
     */
    @Override
    public MEntry selectMEntryByEntryId(Long entryId)
    {
        return mEntryMapper.selectMEntryByEntryId(entryId);
    }

    /**
     * 查询入库管理列表
     * 
     * @param mEntry 入库管理
     * @return 入库管理
     */
    @Override
    public List<MEntry> selectMEntryList(MEntry mEntry)
    {
        return mEntryMapper.selectMEntryList(mEntry);
    }

    /**
     * 新增入库管理
     * 
     * @param mEntry 入库管理
     * @return 结果
     */
    @Override
    public int insertMEntry(MEntry mEntry)
    {
        MStock mStock1=mStockMapper.selectMstock(mEntry.getCommodityId(),mEntry.getWarehouseId());

        if (mStock1==null){
            //如果没有，则新增库存
            insertStock(mEntry);
        }else {
            //如果存在，则更新库存
            updateStock(mEntry,mStock1);
        }
        //如果没有对应的入库单id单号，则新增入库单
        if(mEntryMapper.selectMEntryByEntryId(mEntry.getEntryId())==null){
            return mEntryMapper.insertMEntry(mEntry);
        }
        return 1;
    }

    /**
     * 修改入库管理
     * 
     * @param mEntry 入库管理
     * @return 结果
     */
    @Override
    public int updateMEntry(MEntry mEntry)
    {
        //查询修改前入库单
        MEntry mEntry1=mEntryMapper.selectMEntryByEntryId(mEntry.getEntryId());
        //查询库存
        MStock mStock2=mStockMapper.selectMstock(mEntry1.getCommodityId(),mEntry1.getWarehouseId());
        if (mStock2==null){
            return 0;
        }

        //如果改变的仓库和商品不一样
        if(mEntry.getWarehouseId()!=mEntry1.getWarehouseId()||mEntry.getCommodityId()!=mEntry1.getCommodityId()){
            //如果库存数量修改后小于0，则不能删除
            if (mStock2.getStockQuantity()<mEntry.getEntryQuantity()){
                return 0;
            }
        else {

                //删除库存，传入库存对象，入库单对象
                deleteStock(mStock2, mEntry1);

                //新增库存，传入入库单对象
                insertMEntry(mEntry);
            }
        }
        //如果库存数量修改后小于0，则不能修改
        else if (mStock2.getStockQuantity()<mEntry1.getEntryQuantity()-mEntry.getEntryQuantity()){
            return 0;
        }
        else {
            //修改库存，传入库存对象，修改前的入库单对象，修改后的入库单对象
            updateStock1(mStock2,mEntry1,mEntry);
        }
        return mEntryMapper.updateMEntry(mEntry);
    }



    /**
     * 批量删除入库管理
     * 
     * @param entryIds 需要删除的入库管理主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMEntryByEntryIds(Long[] entryIds)
    {
        //查询入库单
        List<MEntry> mEntryList=mEntryMapper.selectMEntryByEntryIds(entryIds);
        //给入库单分类存入map集合中
        Map<Long,List<MEntry>> map=new HashMap<>();
        for (MEntry mEntry:mEntryList){
            if (map.containsKey(mEntry.getWarehouseId())){
                map.get(mEntry.getWarehouseId()).add(mEntry);
            }else {
                List<MEntry> list=new ArrayList<>();
                list.add(mEntry);
                map.put(mEntry.getWarehouseId(),list);
            }
        }
        //遍历map集合，删除库存
        for (Map.Entry<Long,List<MEntry>> entry:map.entrySet()){
            MStock mStock=mStockMapper.selectMstock(entry.getValue().get(0).getCommodityId(),entry.getKey());
            Long entryQuantity=mStock.getStockQuantity();
            //如果库存数量修改后小于0，则不能删除
            for (MEntry mEntry:entry.getValue()){
                //遍历每个仓库中要删除的商品数量，如果最后库存小于0则操作失败
                entryQuantity=entryQuantity-mEntry.getEntryQuantity();
                if (entryQuantity<0){
                    return 0;
                }
            }
        }
        for (Map.Entry<Long,List<MEntry>> entry:map.entrySet()) {
            MStock mStock=new MStock();
            for (MEntry mEntry : entry.getValue()) {
                //每一次修改库存信息都需要重新查询一次
                mStock = mStockMapper.selectMstock(mEntry.getCommodityId(), mEntry.getWarehouseId());
                deleteStock(mStock, mEntry);
            }
        }
        return mEntryMapper.deleteMEntryByEntryIds(entryIds);
    }

    /**
     * 删除入库管理信息
     * 
     * @param entryId 入库管理主键
     * @return 结果
     */
    @Override
    public int deleteMEntryByEntryId(Long entryId)
    {
//        //查询入库单
//        MEntry mEntry=mEntryMapper.selectMEntryByEntryId(entryId);
//        //查询库存
//        MStock mStock3=mStockMapper.selectMstock(mEntry.getCommodityId(),mEntry.getWarehouseId());
//        //如果库存数量修改后小于0，则不能删除
//        if (mStock3.getStockQuantity()<mEntry.getEntryQuantity()){
//            return 0;
//        }
//        else {
//            //删除库存，传入库存对象，入库单对象
//            deleteStock(mStock3,mEntry);
//        }
        return mEntryMapper.deleteMEntryByEntryId(entryId);
    }



    //查询库存中的仓库列表
    @Override
    public List<MWarehouse> selectWarehouseList() {
        return mEntryMapper.selectWarehouseList();
    }

    //查询当前仓库中的商品
    @Override
    public List<MCommodity> selectCommodityList() {
        return mEntryMapper.selectCommodityList();
    }

    //新增库存
    private void insertStock(MEntry mEntry){
        MStock mStock=new MStock();
        mStock.setCommodityId(mEntry.getCommodityId());
        mStock.setWarehouseId(mEntry.getWarehouseId());
        mStock.setStockQuantity(mEntry.getEntryQuantity());
        mStock.setStockPrice(mEntry.getEntryPrice());
        //计算总金额
        mStock.setStockAmount(mEntry.getEntryPrice().multiply(new BigDecimal(mEntry.getEntryQuantity())));
        mStockMapper.insertMStock(mStock);
    }

    //入库修改库存
    private void updateStock(MEntry mEntry,MStock mStock1){
        MStock mStock=new MStock();
        mStock.setStockId(mStock1.getStockId());
        mStock.setWarehouseId(mEntry.getWarehouseId());
        mStock.setCommodityId(mEntry.getCommodityId());
        //计算总金额
        mStock.setStockAmount(mEntry.getEntryPrice().multiply(new BigDecimal(mEntry.getEntryQuantity()))
                .add(mStock1.getStockAmount()));
        //计算库存数量
        mStock.setStockQuantity(mStock1.getStockQuantity()+mEntry.getEntryQuantity());
        //计算库存单价
        mStock.setStockPrice(mStock.getStockAmount().divide(new BigDecimal(mStock.getStockQuantity()),2,BigDecimal.ROUND_HALF_UP));
        mStockMapper.updateMStock(mStock);
    }

    //入库单修改后，修改库存
    private void updateStock1(MStock mStock2, MEntry mEntry1, MEntry mEntry) {
        MStock mStock=new MStock();
        mStock.setStockId(mStock2.getStockId());
        mStock.setWarehouseId(mStock2.getWarehouseId());
        mStock.setCommodityId(mStock2.getCommodityId());
        //计算总金额，库存金额+修改后的入库金额-修改前的入库金额
        mStock.setStockAmount(mStock2.getStockAmount().add(mEntry.getEntryPrice().multiply(new BigDecimal(mEntry.getEntryQuantity())))
                .subtract(mEntry1.getEntryPrice().multiply(new BigDecimal(mEntry1.getEntryQuantity()))));
        //计算库存数量,库存数量+修改后的入库数量-修改前的入库数量
        mStock.setStockQuantity(mStock2.getStockQuantity()+mEntry.getEntryQuantity()-mEntry1.getEntryQuantity());
        //计算库存单价,总金额/库存数量
        if(mStock.getStockQuantity()!=0){
        mStock.setStockPrice(mStock.getStockAmount().divide(new BigDecimal(mStock.getStockQuantity()),2,BigDecimal.ROUND_HALF_UP));
        }
        else {
            mStock.setStockPrice(new BigDecimal(0));
        }
        //修改库存
        mStockMapper.updateMStock(mStock);
    }

    //入库单删除后，修改库存
    private void deleteStock(MStock mStock3, MEntry mEntry) {
        MStock mStock4=new MStock();
        mStock4.setStockId(mStock3.getStockId());
        mStock4.setWarehouseId(mStock3.getWarehouseId());
        mStock4.setCommodityId(mStock3.getCommodityId());
        //计算总金额，库存金额-删除的入库金额
        mStock4.setStockAmount(mStock3.getStockAmount().subtract(mEntry.getEntryPrice().multiply(new BigDecimal(mEntry.getEntryQuantity()))));
        //计算库存数量,库存数量-删除的入库数量
        mStock4.setStockQuantity(mStock3.getStockQuantity()-mEntry.getEntryQuantity());
        //计算库存单价,总金额/库存数量
        if(mStock4.getStockQuantity()!=0){
            mStock4.setStockPrice(mStock4.getStockAmount().divide(new BigDecimal(mStock4.getStockQuantity()),2,BigDecimal.ROUND_HALF_UP));
        } else {
            mStock4.setStockPrice(new BigDecimal(0));
        }
        mStockMapper.updateMStock(mStock4);
    }
}
